// FImageDialog.cpp (c) 2011 JV Software
//

#include "FallenPlugin.h"
#include "bitmap32.h"

#include <il/il.h>
#include <il/ilu.h>
#include <il/ilut.h>

FImageDialog	*dialog = NULL;

extern "C" void ILAPIENTRY iRestoreReadFuncs(void);

//
// FImageDialog
//
FImageDialog::FImageDialog() {
	Init( IDD_IMAGECONVERTER );
	pendingImage = false;
}

/*
==============
FImageDialog::Init
==============
*/
void FImageDialog::Init( int resourceId ) {
	FString comprType[] = { TEXT("RGBA"), TEXT("DXT1"), TEXT("DXT3"), TEXT("DXT5") };

	FPluginDialog::Init( resourceId );

	AddMenu( IDR_IMAGECONV_MENU );

	PopulateComboBox( IDC_IMGFORMAT, 4, comprType );

	ilGenImages(1, &image);
	ilGenImages(1, &imagePreview);
}

/*
==============
FImageDialog::EnableOptions
==============
*/
void FImageDialog::EnableOptions( void ) {
	EnableControl( IDC_IMGFORMAT );
	EnableControl( ID_FILE_SAVETEXTURE );
}

/*
==============
FImageDialog::BlitImageData
==============
*/
void FImageDialog::BlitImageData( int pictureControl, byte *data, unsigned int width, unsigned int height, unsigned int bpp ) {
	HWND hwnd;

	Bitmap32 bitmap(width, height);

	memcpy(bitmap.GetPixels(), data, width * height * bpp );

	hwnd  = GetDlgItem (dialogHwnd, pictureControl);        // clear the containing control
    HDC hdc = GetDC( hwnd );

	HDC mydc = bitmap.GetDC();
	RECT r;
	GetWindowRect( hwnd, &r );

	int w = r.right - r.left;
	int h = r.bottom - r.top;

	// Fixes the nasty purple streak issue.
	SetStretchBltMode( hdc, HALFTONE );

	float sngRatioW;
    float sngRatioH;

	if( width > height ) {
        sngRatioW = 1;
        sngRatioH = (float)width / (float)height;
	}
	else {
        sngRatioW = (float)height / (float)width;
        sngRatioH = 1;
	}


	if(!StretchBlt( hdc, 0, 0, w / sngRatioW, h / sngRatioH, mydc, 0, 0, width, height, SRCCOPY )) {
		MGlobal::displayError("BitBlt failed" );
	}
}

void FImageDialog::MLoadImage( const char *str ) {
	ILubyte *Lump;
	ILuint Size;
	FILE *File;
	ILenum type = IL_BMP;

	File = fopen(str, "rb");
	fseek(File, 0, SEEK_END);
	Size = ftell(File);

	Lump = (ILubyte*)malloc(Size);
	fseek(File, 0, SEEK_SET);
	fread(Lump, 1, Size, File);
	fclose(File);

	if(!ilLoadL(IL_TGA, Lump, Size)) {
		if(!ilLoadL(IL_PNG, Lump, Size)) {
			if(!ilLoadL(IL_BMP, Lump, Size)) {
				if(!ilLoadL(IL_JPG, Lump, Size)) {
					MGlobal::displayError( "ilLoad Failure" );
				}
			}
		}
	}
	free(Lump);
}

/*
==============
FImageDialog::ConvertAndBlitImage
==============
*/
void FImageDialog::ConvertAndBlitImage( unsigned int format ) {
	ilConvertImage(format, IL_UNSIGNED_BYTE);

	ILubyte *Data = ilGetData();
	BlitImageData( IDC_BEFOREIMAGE, Data, ilGetInteger( IL_IMAGE_WIDTH ), ilGetInteger( IL_IMAGE_HEIGHT ), ilGetInteger( IL_IMAGE_BPP ) );
}

/*
==============
FImageDialog::WriteImage
==============
*/
void FImageDialog::WriteImage( string filename, FTextureFormat_t format ) {
	FILE	*texFile = fopen( filename.c_str(), "wb" );
	FTextureHeader_t header;
	byte	*tempBuffer;
	ILuint	bufferSize;

	if(!texFile) {
		MGlobal::displayError( "Failed to write image, IO error." );
		return;
	}

	strcpy((char *)&header.iden, "JTEX");
	header.version = FTEXTURE_VERSION;
	header.format = format;
	header.width = ilGetInteger( IL_IMAGE_WIDTH );
	header.height = ilGetInteger( IL_IMAGE_HEIGHT );
	fwrite( &header, sizeof( FTextureHeader_t ), 1, texFile );

	switch( format ) {
		case TEX_FORMAT_RGBA:
			{
				fwrite( ilGetData(), ilGetInteger( IL_IMAGE_WIDTH ) * ilGetInteger( IL_IMAGE_HEIGHT ) * ilGetInteger( IL_IMAGE_BPP ), 1, texFile );
			}
		case TEX_FORMAT_DXT1:
			{
				tempBuffer = ilCompressDXT( ilGetData(), ilGetInteger( IL_IMAGE_WIDTH ), ilGetInteger( IL_IMAGE_HEIGHT ), ilGetInteger( IL_IMAGE_BPP ), IL_DXT1, &bufferSize );
				fwrite( tempBuffer, bufferSize, 1, texFile );
			}
			break;
		case TEX_FORMAT_DXT3:
			{
				tempBuffer = ilCompressDXT( ilGetData(), ilGetInteger( IL_IMAGE_WIDTH ), ilGetInteger( IL_IMAGE_HEIGHT ), ilGetInteger( IL_IMAGE_BPP ), IL_DXT3, &bufferSize );
				fwrite( tempBuffer, bufferSize, 1, texFile );
			}
			break;
		case TEX_FORMAT_DXT5:
			{
				tempBuffer = ilCompressDXT( ilGetData(), ilGetInteger( IL_IMAGE_WIDTH ), ilGetInteger( IL_IMAGE_HEIGHT ), ilGetInteger( IL_IMAGE_BPP ), IL_DXT5, &bufferSize );
				fwrite( tempBuffer, bufferSize, 1, texFile );
			}
			break;
	}

	fclose( texFile );
}

/*
==============
FImageDialog::OnCommand
==============
*/
void FImageDialog::OnCommand( int cmd ) {
	switch( cmd ) {
		case ID_FILE_SAVETEXTURE:
			{
				if(!pendingImage) {
					return;
				}
				string fileName = M_SaveFileDialog( "Texture File (*.ftex*)\0*.ftex*\0" );

				WriteImage( fileName, (FTextureFormat_t)GetSelectionFromControl( IDC_IMGFORMAT ) );
			}
		break;
		case ID_FILE_OPENIMAGE:
			{
				string fileName = M_OpenFileDialog( "PNG File (*.png*)\0*.png*\0|DDS File (*.dds*)\0*.dds*\0|BMP File (*.bmp*)\0*.bmp*\0|TGA File (*.tga*)\0*.tga*\0|JPG File (*.jpg*)\0*.jpg*\0", dialogHwnd );
				if(fileName.size() <= 0) {
					return;
				}

				iRestoreReadFuncs();
				ilBindImage( image );
				MLoadImage(fileName.c_str() );

				ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);

				ilBindImage( imagePreview );
				MLoadImage(fileName.c_str() );

				ConvertAndBlitImage( IL_RGBA );
				
				EnableOptions();
				pendingImage = true;
			}
			break;
	}
}

/*
==============
FImageDialogCmd::doIt
==============
*/
MStatus FImageDialogCmd::doIt( const MArgList& args )
{
	if(dialog == NULL) {
		dialog = new FImageDialog();
	}
	dialog->Show();
	return MS::kSuccess;
}

